package com.whfc.base.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.whfc.base.dao.AppSyncMapper;
import com.whfc.base.dto.AppSyncDTO;
import com.whfc.base.dto.SyncCacheKey;
import com.whfc.base.enums.AppSyncModule;
import com.whfc.base.redis.SyncConfigRedisDao;
import com.whfc.base.service.SyncConfigService;
import com.whfc.common.enums.SyncPlatform;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.HttpUtil;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2020-11-27 11:29
 */
@DubboService(interfaceClass = SyncConfigService.class, version = "1.0.0")
public class SyncConfigServiceImpl implements SyncConfigService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public final String szjTokenKey = "sync::{0}::{1}";
    public final String syncPlatformTokenKey = "sync::{0}";

    public final String URL = "https://sc.uni-ubi.com/sc/api";
    /**
     * 空配置dto
     */
    private AppSyncDTO noSyncDTO = new AppSyncDTO();

    /**
     * 同步配置缓存
     */
    private LoadingCache<SyncCacheKey, AppSyncDTO> syncConfigCache =
            CacheBuilder.newBuilder()
                    .initialCapacity(128)
                    .maximumSize(1024)
                    .expireAfterAccess(5, TimeUnit.MINUTES)
                    .build(new CacheLoader<SyncCacheKey, AppSyncDTO>() {
                        @Override
                        public AppSyncDTO load(SyncCacheKey key) throws Exception {
                            AppSyncDTO syncDTO = appSyncMapper.selectAppSync(key.getDeptId(), key.getPlatform(), key.getModule());
                            if (syncDTO == null) {
                                syncDTO = noSyncDTO;
                            }
                            return syncDTO;
                        }
                    });

    @Autowired
    private AppSyncMapper appSyncMapper;

    @Autowired
    private SyncConfigRedisDao syncConfigRedisDao;

    @Override
    public AppSyncDTO getSyncConfig(SyncPlatform syncPlatform, Integer deptId) throws BizException {
        logger.info("getSyncConfig,platform:{},deptId:{}", syncPlatform, deptId);
        SyncCacheKey key = new SyncCacheKey(deptId, syncPlatform.getValue(), null);
        AppSyncDTO syncDTO = null;
        try {
            syncDTO = syncConfigCache.get(key);
            if (noSyncDTO.equals(syncDTO)) {
                return null;
            }
        } catch (Exception ex) {
            logger.error("获取同步配置错误", ex);
        }
        return syncDTO;
    }

    @Override
    public AppSyncDTO getSyncConfig(SyncPlatform syncPlatform, Integer deptId, AppSyncModule syncModule) {
        logger.info("getSyncConfig,platform:{},deptId:{},syncModule:{}", syncPlatform, deptId, syncModule);
        SyncCacheKey key = new SyncCacheKey(deptId, syncPlatform.getValue(), syncModule.getCode());
        AppSyncDTO syncDTO = null;
        try {
            syncDTO = syncConfigCache.get(key);
            if (noSyncDTO.equals(syncDTO)) {
                return null;
            }
        } catch (Exception ex) {
            logger.error("获取同步配置错误", ex);
        }
        return syncDTO;
    }

    @Override
    public List<AppSyncDTO> selectByPlatform(Integer platform) throws BizException {
        return appSyncMapper.selectByPlatform(platform);
    }

    @Override
    public String getSZJSyncToken(Integer deptId, Integer platform, String secret) {
        String key = MessageFormat.format(szjTokenKey, deptId, platform);
        String szjToken = syncConfigRedisDao.getSZJToken(key);
        if (StringUtils.hasText(szjToken)) {
            return szjToken;
        }
        String path = "/v1/api/verify/getToken";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("secret", secret);
        String s = HttpUtil.doPost(URL + path, JSONObject.toJSONString(jsonObject));
        JSONObject result = JSONObject.parseObject(s);
        JSONObject data = result.getJSONObject("data");
        String token = data.getString("token");
        syncConfigRedisDao.setSZJToken(key, token, 5);
        return token;
    }

    @Override
    public String getShiShouSyncToken(String appKey, String appSecret, String host) {
        String key = MessageFormat.format(syncPlatformTokenKey, "shishou");
        String syncPlatformToken = syncConfigRedisDao.getValue(key);
        if (StringUtils.hasText(syncPlatformToken)) {
            return syncPlatformToken;
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("username", appKey);
        jsonObject.put("password", appSecret);
        String getToken = "/api/v1/uploadApi/getToken";
        String result = HttpUtil.doPost(host + getToken, JSONObject.toJSONString(jsonObject));
        JSONObject jsonData = JSONObject.parseObject(result);
        logger.info("调用结果：{}", jsonData);
        if (200 != jsonData.getInteger("code")) {
            throw new BizException(ResultEnum.UNKNOWN_ERROR.getCode(), jsonData.getString("msg"));
        }
        JSONObject data = jsonData.getJSONObject("data");
        String token = data.getString("token");
        syncConfigRedisDao.setValue(key, token, 1);
        return token;
    }
}
